#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>



static long jdo_fork(unsigned long clone_flags,
							unsigned long stack_start,
							unsigned long stack_size,
							int __user *parent_tidptr,
							int __user *child_tidptr)
{
	pr_info("<%s>: clone_flags = 0x%lx, stack_start = 0x%lx "
					"stack_size = 0x%lx\n", __func__, clone_flags, stack_start, stack_size);	

	return 0;
}

static struct jprobe my_jprobe = {
	.entry = jdo_fork,
	.kp = {
		.symbol_name = "do_fork",
	},
};

static int jprobe_module_init(void)
{
	int ret;

	ret = register_jprobe(&my_jprobe);
	if (ret < 0) {
		pr_info("register_jprobe failed, ret:%d\n", ret);
		return -1;
	}

	pr_info("Planted jprobe at %p, handler addr %p\n",
					my_jprobe.kp.addr, my_jprobe.entry);
	
	return 0;
}

static void jprobe_module_exit(void)
{
	unregister_jprobe(&my_jprobe);
	pr_info("jprobe at %p unregistered\n", my_jprobe.kp.addr);
	
	return ;
}

module_init(jprobe_module_init);
module_exit(jprobe_module_exit);

MODULE_LICENSE("GPL");

